import { debounce, every } from 'lodash';
// 引入 echarts 核心模块，核心模块提供了 echarts 使用必须要的接口。
import * as Echarts from 'echarts/core';
// 引入 Canvas 渲染器，注意引入 CanvasRenderer 或者 SVGRenderer 是必须的一步
import { CanvasRenderer } from 'echarts/renderers';
// 引入柱状图图表，图表后缀都为 Chart
import { PieChart, BarChart, LineChart } from 'echarts/charts';
// 引入提示框，标题组件，组件后缀都为 Component
import { TitleComponent, TooltipComponent, LegendComponent, GridComponent } from 'echarts/components';
import { h, markRaw, ref, renderSlot } from 'vue';

// 注册必须的组件
Echarts.use([
  CanvasRenderer,
  TitleComponent,
  TooltipComponent,
  LegendComponent,
  GridComponent,
  PieChart,
  BarChart,
  LineChart,
]);

const EchartsCore = {
  name: 'EchartsCore',
  props: {
    components: { type: Array, default: () => [] },
    options: { type: Object, default: () => ({}) },
    enableEmpty: { type: Boolean, default: true },
  },
  emits: ['ready', 'rendered'],
  setup(props) {
    Echarts.use(props.components);

    let chart = null;
    let ready = ref(false);
    let isEmpty = ref(false);

    return { chart, ready, isEmpty };
  },
  mounted() {
    this.chart = markRaw(Echarts.init(this.$refs.container));
    this.$watch(
      () => this.options,
      debounce(function (options) {
        if (!options || typeof options !== 'object') {
          return;
        }
        let series = options.series || [];
        series = Array.isArray(series) ? series : [series];
        if (this.enableEmpty !== false) {
          this.isEmpty = every(series, (item) => {
            return !item || !item.data || !item.data.length;
          });
        }
        this.renderChart();
      }, 300),
      { immediate: true, deep: true },
    );
    this.onWinResize = () => {
      this.chart && this.chart.resize();
    };
    if (window.ResizeObserver) {
      this.resizeObserver = new ResizeObserver(() => {
        this.onWinResize();
      });
      this.resizeObserver.observe(this.$refs.container);
    } else {
      window.addEventListener('resize', this.onWinResize);
    }
    this.ready = true;
    this.$emit('ready', { chart: this.chart, echarts: Echarts });
  },
  unmounted() {
    window.removeEventListener('resize', this.onWinResize);
    if (this.resizeObserver) {
      this.resizeObserver.disconnect();
    }
    if (this.chart) {
      this.chart.dispose();
    }
  },
  methods: {
    renderChart() {
      if (!this.isEmpty && this.chart && this.options && typeof this.options === 'object') {
        this.chart.setOption(this.options);
        this.$emit('rendered', { chart: this.chart, echarts: Echarts });
      }
    },
    dispatchAction(opt = {}) {
      if (this.chart && opt && opt.type) {
        this.chart.dispatchAction(opt);
      }
    },
    on() {
      if (this.chart && arguments[0]) {
        this.chart.on.apply(this.chart, arguments);
      }
    },
    off() {
      if (this.chart && arguments[0]) {
        this.chart.off.apply(this.chart, arguments);
      }
    },
  },
  render() {
    let _props = {
      chart: this.chart,
      style: { position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%,-50%)' },
    };
    return h('div', { style: { width: '100%', height: '100%', position: 'relative' } }, [
      h('div', {
        ref: 'container',
        name: 'container',
        style: { width: '100%', height: '100%', margin: 0, display: !this.isEmpty ? null : 'none' },
      }),
      this.isEmpty
        ? h('div', { style: _props.style }, this.$slots.empty ? renderSlot(this.$slots, 'empty') : '~暂无数据~')
        : this.ready
          ? renderSlot(this.$slots, 'default', _props)
          : null,
    ]);
  },
};

export { EchartsCore as default, Echarts };
